const { utils } = require('board-game');

const VsSoldier = require("./soldier");

const { game: gameConfig } = require('./config');
const Buff = require('./buff');

class VsHome {
    constructor(group) {
        this.group = group;
        this.winCount = 0;
        this.reset();
    }

    doHelp() {
        this.grow(1);
        this.help = true;
    }

    reset() {
        this.troops = [];
        this.reinforces = [];
        this.help = false;
        this.grow(10 + (this.group.roles.length - 1) * 5);
    }
    grow(value) {
        for (let i = 0; i < value; i++) {
            let index = 1;
            while(this.troops.some(soldier => soldier.index === index)) {
                index++;
            }
            this.troops.push(new VsSoldier(index));
        }
        this.troops.sort((a, b) => a.index - b.index);
    }
    kill(value, onlyNormal = false) {
        let soldiers = this.troops.filter(soldier => !soldier.isDie() && soldier.canKill() && (!onlyNormal || !soldier.hasBuff()));
        let deadSoldiers = soldiers.slice(Math.max(0, soldiers.length - value));
        for (let soldier of deadSoldiers) {
            soldier.dead();
        }
        return deadSoldiers.length;
    }
    buff(count, type, role) {
        let soldiers = this.troops.filter(soldier => !soldier.hasBuff() && !soldier.isDie());
        if (soldiers.length > count) {
            soldiers = soldiers.slice(0, count);
        }
        for (let soldier of soldiers) {
            soldier.setBuff(type, role);
        }
    }
    debuff(count, type) {
        let soldiers = this.troops.filter(soldier => (typeof type === 'undefined' || soldier.isBuff(type)) && !soldier.isDie());
        if (soldiers.length > count) {
            soldiers.sort((a, b) => a.buffTime() - b.buffTime());
            soldiers = soldiers.slice(soldiers.length - count);
        }
        for (let soldier of soldiers) {
            soldier.clearBuff();
        }
    }
    clearBuff() {
        for (let soldier of this.troops) {
            soldier.clearBuff();
        }
        this.reinforces = [];
    }
    addReinforce(role, value) {
        this.reinforces.push({
            role, value, distance: 3, time: +Date.now()
        })
    }
    removeReinforce(value) {
        for (let i = 0; i < value; i++) {
            if (this.reinforces.length) {
                let index = Math.floor(this.reinforces.length * Math.random());
                this.reinforces.splice(index, 1);
            }
        }
    }
    tick() {
        for (let index = this.troops.length - 1; index >= 0; index--) {
            if (this.troops[index].deadTick) {
                this.troops[index].deadTick++;
                if (this.troops[index].deadTick >= gameConfig.clocks.dead) {
                    this.troops.splice(index, 1);
                }
            }
        }
    }
    checkStart(role) {
        for (let type of Object.keys(Buff.type)) {
            if (Buff[type] && Buff[type].checkStart) {
                Buff[type].checkStart(role, this);
            }
        }

        for (let index = this.reinforces.length - 1; index >= 0; index--) {
            let reinforce = this.reinforces[index];
            if (reinforce.role === role) {
                reinforce.distance--;
                if (reinforce.distance == 0) {
                    this.reinforces.splice(index, 1);
                    this.grow(reinforce.value);
                }
            }
        }
    }
    get data() {
        return {
            index: this.group.index,
            color: this.group.option.color,
            value: this.troops.length,
            troops: utils.asObject(this.troops.map(soldier => soldier.data)),
            reinforces: utils.asObject(this.reinforces.map(reinforce => ({ role: reinforce.role.summary, value: reinforce.value, distance: reinforce.distance }))),
            help: this.help,
            winCount: this.winCount,
        }
    }
}

module.exports = VsHome;